<html>
  <head>
    <title>Application Logs</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <section class="section" style="height: 100%">
        <div class="container columns" style="height: 100%">
          <nav class="panel column is-3">
            <p class="panel-heading">Level</p>

            <div v-for="lvl in levels">
              <label class="checkbox">
                <input type="checkbox" v-model="enabled_levels[lvl]">
                {{lvl}}
              </label>
            </div>

            <p class="panel-heading">Process</p>

            <div v-for="proc in processes">
              <label class="checkbox">
                <input type="checkbox" v-model="enabled_processes[proc]">
                {{proc}}
              </label>
            </div>
          </nav>

          <div class="column" style="height: 100%">
            <div class="table-container" style="overflow-y: scroll; height: 100%;">
              <table class="table">
                <thead>
                  <tr>
                    <th>Process</th>
                    <th>Level</th>
                    <th>Timestamp</th>
                    <th>Content</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="msg in messages" :key="msg.idx" v-if="enabled_processes[msg.proc] && enabled_levels[msg.level]">
                    <th>{{msg.proc}}</th>
                    <th>{{msg.level}}</th>
                    <th>{{msg.timestamp}}</th>
                    <th>{{msg.content}}</th>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </section>
    </div>

    <script>
      const vueobj = new Vue({
        el: "#app",
        data: {
          processes: [],
          levels: ["DBG", "INFO", "WARN", "ERR", "CRIT"],
          messages: [],
          enabled_processes: {},
          enabled_levels: {"DBG": true, "INFO": true, "WARN": true, "ERR": true, "CRIT": true},
          discovery_ws: null,
          log_ws: [],
          idx: 0,
        },
        mounted() {
          const vm = this;
          vm.discovery_ws = new WebSocket(`ws://localhost:24880/wsapi/discover`)
          vm.discovery_ws.onopen = () => {
            vm.discovery_ws.send(JSON.stringify({
              protocol: "log",
              topic: "**/*",
            }))
          }
          vm.discovery_ws.onmessage = (evt) => {
            const topic = JSON.parse(evt.data).topic
            vm.processes.push(topic)
            vm.processes = vm.processes.sort()
            vm.enabled_processes[topic] = false
            vm.start_listen(topic)
          }
        },
        methods: {
          start_listen(topic) {
            const vm = this;
            const ws = new WebSocket(`ws://localhost:24880/wsapi/log`)
            ws.onopen = () => {
              ws.send(JSON.stringify({
                topic,
                level: "DBG",
                init: "OLDEST",
                iter: "NEXT",
              }))
            }
            ws.onmessage = (evt) => {
              const info = JSON.parse(evt.data)
              let log_level = undefined
              let timestamp = undefined
              for (let kv of info.headers) {
                if (kv[0] == "a0_log_level") {
                  log_level = kv[1]
                }
                if (kv[0] == "a0_time_wall") {
                  timestamp = kv[1]
                }
              }
              vm.messages.push({
                proc: topic,
                level: log_level,
                timestamp: timestamp,
                content: info.payload,
                idx: vm.idx,
              })
              vm.idx++

              if (vm.messages.length > 1000) {
                vm.messages.shift()
              }
            }
            vm.log_ws.push(ws)
          },
        }
      });
    </script>
  </body>
</html>
